"""
IP管理缓存模块
提供IP地址数据的缓存机制，提升查询性能
"""

import logging
import time
from typing import Dict, Any, Optional, List
from threading import Lock

logger = logging.getLogger(__name__)

class IpCache:
    """IP管理缓存类"""
    
    def __init__(self, cache_timeout: int = 300):  # 5分钟缓存超时
        self.cache_timeout = cache_timeout
        self.ip_cache: Dict[str, Dict[str, Any]] = {}
        self.statistics_cache: Dict[str, Any] = {}
        self.list_cache: Dict[str, List[Dict[str, Any]]] = {}
        self.cache_timestamps: Dict[str, float] = {}
        self.lock = Lock()
        
        logger.info("IP管理缓存初始化完成")
    
    def get_ip(self, ip: str) -> Optional[Dict[str, Any]]:
        """
        获取IP缓存数据
        
        Args:
            ip: IP地址
            
        Returns:
            IP信息或None
        """
        with self.lock:
            cache_key = f"ip_{ip}"
            
            # 检查缓存是否存在且未过期
            if (cache_key in self.ip_cache and 
                cache_key in self.cache_timestamps and
                time.time() - self.cache_timestamps[cache_key] < self.cache_timeout):
                
                logger.debug(f"从缓存获取IP信息: {ip}")
                return self.ip_cache[cache_key].copy()
        
        return None
    
    def set_ip(self, ip: str, ip_data: Dict[str, Any]) -> None:
        """
        设置IP缓存数据
        
        Args:
            ip: IP地址
            ip_data: IP数据
        """
        with self.lock:
            cache_key = f"ip_{ip}"
            self.ip_cache[cache_key] = ip_data.copy()
            self.cache_timestamps[cache_key] = time.time()
            logger.debug(f"IP信息已缓存: {ip}")
    
    def get_statistics(self) -> Optional[Dict[str, Any]]:
        """
        获取统计信息缓存
        
        Returns:
            统计信息或None
        """
        with self.lock:
            cache_key = "statistics"
            
            if (cache_key in self.statistics_cache and 
                cache_key in self.cache_timestamps and
                time.time() - self.cache_timestamps[cache_key] < self.cache_timeout):
                
                logger.debug("从缓存获取统计信息")
                return self.statistics_cache[cache_key].copy()
        
        return None
    
    def set_statistics(self, statistics: Dict[str, Any]) -> None:
        """
        设置统计信息缓存
        
        Args:
            statistics: 统计信息
        """
        with self.lock:
            cache_key = "statistics"
            self.statistics_cache[cache_key] = statistics.copy()
            self.cache_timestamps[cache_key] = time.time()
            logger.debug("统计信息已缓存")
    
    def get_ip_list(self, filters_hash: str) -> Optional[List[Dict[str, Any]]]:
        """
        获取IP列表缓存
        
        Args:
            filters_hash: 筛选条件的哈希值
            
        Returns:
            IP列表或None
        """
        with self.lock:
            cache_key = f"list_{filters_hash}"
            
            if (cache_key in self.list_cache and 
                cache_key in self.cache_timestamps and
                time.time() - self.cache_timestamps[cache_key] < self.cache_timeout):
                
                logger.debug(f"从缓存获取IP列表: {filters_hash}")
                return [item.copy() for item in self.list_cache[cache_key]]
        
        return None
    
    def set_ip_list(self, filters_hash: str, ip_list: List[Dict[str, Any]]) -> None:
        """
        设置IP列表缓存
        
        Args:
            filters_hash: 筛选条件的哈希值
            ip_list: IP列表
        """
        with self.lock:
            cache_key = f"list_{filters_hash}"
            self.list_cache[cache_key] = [item.copy() for item in ip_list]
            self.cache_timestamps[cache_key] = time.time()
            logger.debug(f"IP列表已缓存: {filters_hash}")
    
    def invalidate_ip(self, ip: str) -> None:
        """
        使特定IP缓存失效
        
        Args:
            ip: IP地址
        """
        with self.lock:
            cache_key = f"ip_{ip}"
            if cache_key in self.ip_cache:
                del self.ip_cache[cache_key]
            if cache_key in self.cache_timestamps:
                del self.cache_timestamps[cache_key]
            logger.debug(f"IP缓存已失效: {ip}")
    
    def invalidate_list_cache(self) -> None:
        """使所有列表缓存失效"""
        with self.lock:
            keys_to_remove = [key for key in self.list_cache.keys()]
            for key in keys_to_remove:
                del self.list_cache[key]
            
            keys_to_remove = [key for key in self.cache_timestamps.keys() if key.startswith("list_")]
            for key in keys_to_remove:
                del self.cache_timestamps[key]
            
            logger.debug("所有列表缓存已失效")
    
    def invalidate_statistics_cache(self) -> None:
        """使统计信息缓存失效"""
        with self.lock:
            cache_key = "statistics"
            if cache_key in self.statistics_cache:
                del self.statistics_cache[cache_key]
            if cache_key in self.cache_timestamps:
                del self.cache_timestamps[cache_key]
            logger.debug("统计信息缓存已失效")
    
    def clear_cache(self) -> None:
        """清除所有缓存"""
        with self.lock:
            self.ip_cache.clear()
            self.statistics_cache.clear()
            self.list_cache.clear()
            self.cache_timestamps.clear()
            logger.info("所有IP缓存已清除")
    
    def get_cache_info(self) -> Dict[str, Any]:
        """
        获取缓存信息
        
        Returns:
            缓存统计信息
        """
        with self.lock:
            current_time = time.time()
            expired_keys = []
            
            # 检查过期的缓存键
            for key, timestamp in self.cache_timestamps.items():
                if current_time - timestamp >= self.cache_timeout:
                    expired_keys.append(key)
            
            return {
                'ip_cache_count': len(self.ip_cache),
                'statistics_cache_count': len(self.statistics_cache),
                'list_cache_count': len(self.list_cache),
                'total_cache_count': len(self.cache_timestamps),
                'expired_cache_count': len(expired_keys),
                'cache_timeout': self.cache_timeout
            }
    
    def cleanup_expired_cache(self) -> None:
        """清理过期的缓存"""
        with self.lock:
            current_time = time.time()
            expired_keys = []
            
            for key, timestamp in self.cache_timestamps.items():
                if current_time - timestamp >= self.cache_timeout:
                    expired_keys.append(key)
            
            for key in expired_keys:
                if key.startswith("ip_"):
                    if key in self.ip_cache:
                        del self.ip_cache[key]
                elif key == "statistics":
                    if key in self.statistics_cache:
                        del self.statistics_cache[key]
                elif key.startswith("list_"):
                    if key in self.list_cache:
                        del self.list_cache[key]
                
                if key in self.cache_timestamps:
                    del self.cache_timestamps[key]
            
            if expired_keys:
                logger.debug(f"清理了{len(expired_keys)}个过期缓存项")
    
    def warm_up_cache(self, ip_service) -> None:
        """
        预热缓存
        
        Args:
            ip_service: IP服务实例
        """
        try:
            # 预加载统计信息
            statistics = ip_service.get_ip_statistics()
            if statistics:
                self.set_statistics(statistics)
            
            # 预加载前100个IP地址
            ip_list = ip_service.get_all_ips()
            for ip_data in ip_list[:100]:
                self.set_ip(ip_data['ip'], ip_data)
            
            logger.info("IP缓存预热完成")
            
        except Exception as e:
            logger.error(f"IP缓存预热失败: {str(e)}")
    
    def generate_filters_hash(self, filters: Dict[str, Any]) -> str:
        """
        生成筛选条件的哈希值
        
        Args:
            filters: 筛选条件
            
        Returns:
            哈希值
        """
        import hashlib
        
        # 将筛选条件转换为字符串并生成哈希
        filter_str = str(sorted(filters.items()))
        return hashlib.md5(filter_str.encode()).hexdigest()[:8]